/**
 * 火柴人的行动逻辑
 */
cc.Class({
    extends: cc.Component,

    properties: {

    },


    onLoad() {
        //开启游戏中的碰撞管理器
        cc.director.getPhysicsManager().enabled = true;
        // cc.director.getPhysicsManager().debugDrawFlags = cc.PhysicsManager.DrawBits.e_aabbBit |
        //     cc.PhysicsManager.DrawBits.e_pairBit |
        //     cc.PhysicsManager.DrawBits.e_centerOfMassBit |
        //     cc.PhysicsManager.DrawBits.e_jointBit |
        //     cc.PhysicsManager.DrawBits.e_shapeBit
        //     ;
        this.initPrivateData();
        this.initPublicData();
        this.initPrivateFunc();
        this.initPublicFunc();
    },

    initPrivateData() {
        this.keyList = {};
        this.funcList = [];
    },

    initPublicData() {
        //过关后的弹框
        this.information = this.node.parent.getChildByName("Main Camera").getChildByName("information");
        this.information.active = false;
        cc.vv.CoinCount = 0;
        cc.vv.DeathNum = 0;
        this.node.prop = "Stand";
        this.node.model = 'Land';
        this.rigidBody = this.node.getComponent(cc.RigidBody);
        this.physicsBoxCollider = this.node.getComponent(cc.PhysicsBoxCollider);
        this.heroBoxHeight = this.physicsBoxCollider.size.height;
        //人物节点的动画组件
        this.animation = this.node.getComponent(cc.Animation);
        //火箭
        let rocket = this.node.parent.getChildByName("prop").getChildByName("rocket_prop");
        this.rocketProp = rocket.getComponent(cc.RigidBody);
    },

    initPrivateFunc() {
        this.initListener();
    },

    initPublicFunc() { },

    /**
     * 开启按键监听
     */
    initListener() {
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, (event) => {
            let keyCode = event.keyCode;
            if (!this.keyList[keyCode]) {
                this.keyList[keyCode] = keyCode;
            }
        });
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, (event) => {
            let keyCode = event.keyCode;
            if (this.keyList[keyCode]) {
                delete this.keyList[keyCode];
            }
        });
    },
    /**
     * 判断人物模式，海陆空执行不同行为逻辑
     * @param {*} type 
     * @param {*} arr 
     */
    listenerManager(type, arr) {
        if (type === "Sea") {
            this.seaManager(arr);
        }
        else if (type === "Land") {
            this.schedule(this.playerCrash, 0.01)
            this.landManager(arr);
        }
        else if (type === "Sky") {
            this.skyManager(arr);
        } else if (type === 'JetTube') {
            this.JetTubeManager(arr);
        }
    },
    /**
     * 水中的逻辑
     */
    seaManager(arr) {
        let isW = arr.indexOf(87) >= 0;
        let isA = arr.indexOf(65) >= 0;
        let isS = arr.indexOf(83) >= 0;
        let isD = arr.indexOf(68) >= 0;

        //左转
        if (isA) {
            this.node.prop = 'Left';
        } else if (isD) {
            //右转
            this.node.prop = 'Right';
        } else if (isW) {
            //向前
            this.node.prop = 'Advance';
        } else if (isS) {
            //向后
            this.node.prop = 'Retreat';
        } else {
            this.node.prop = 'Motionless';
        }
        // this.animation.stop();

        this.seaAction(this.node.prop);
    },
    /**
     * 陆地的逻辑
     */
    landManager(arr) {
        let isW = arr.indexOf(87) >= 0;
        let isA = arr.indexOf(65) >= 0;
        let isS = arr.indexOf(83) >= 0;
        let isD = arr.indexOf(68) >= 0;
        let dir;
        this.node.rotation = 0;
        this.node.currentProp = this.node.prop;
        if (isS && isA && !isD) {//左滚
            cc.vv.isRollFinishedLock = false;
            this.scheduleOnce(() => { cc.vv.isRollFinishedLock = true; }, 0.3)
            this.node.prop = 'Roll';
            dir = -1;

        } else if (isS && isD && !isA) {//右滚
            cc.vv.isRollFinishedLock = false;
            this.scheduleOnce(() => { cc.vv.isRollFinishedLock = true; }, 0.3)
            this.node.prop = 'Roll';
            dir = 1;

        } else if (isW && !cc.vv.isDoubleJump) {//跳

            this.node.prop = 'Jump';
            dir = this.node.scaleX;
        }
        else if (isW && cc.vv.isDoubleJump) {//二段跳
            this.node.prop = 'DoubleJump';
            dir = this.node.scaleX;
        } else if (isA && cc.vv.isRollFinishedLock) {//左跑
            dir = -1;
            if (this.node.currentProp === 'Jump' || this.node.currentProp === 'Fall' || this.node.currentProp === 'DoubleJump') {
                this.landAction('RunLeft', dir);
            } else {
                this.node.prop = 'RunLeft';
            }
        } else if (isD && cc.vv.isRollFinishedLock) {//右跑
            dir = 1;
            if (this.node.currentProp === 'Jump' || this.node.currentProp === 'Fall' || this.node.currentProp === 'DoubleJump') {
                this.landAction('RunRight', dir);
            } else {
                this.node.prop = 'RunRight';
            }
        } else if (isS && cc.vv.isRollFinishedLock) {//蹲
            this.node.prop = 'Down';
            dir = this.node.scaleX;
        } else if (this.node.prop === 'Climb') {//爬墙
            dir = this.node.scaleX;
        } else {
            if (cc.vv.isRollFinishedLock && this.node.prop !== "Fall") {//站立
                this.node.prop = 'Stand';
                cc.vv.isDoubleJump = false;
                dir = this.node.scaleX;
            }

        }
        if (this.node.prop === this.node.currentProp && this.node.prop !== 'Climb') {
            return;
        }
        if (!cc.vv.STATE[this.node.currentProp][this.node.prop] && this.node.prop !== 'Climb') {
            this.node.prop = this.node.currentProp;
            return;
        }
        this.animationManager(this.node.prop);
        this.landAction(this.node.prop, dir);

    },
    /**
     * 空中的逻辑
     */
    skyManager(arr) {
        //let isW = arr.indexOf(87) >= 0;
        let isA = arr.indexOf(65) >= 0;
        //let isS = arr.indexOf(83) >= 0;
        let isD = arr.indexOf(68) >= 0;
        if (isA) {
            this.node.prop = 'rising';
        } else if (isD) {
            this.node.prop = 'decline';
        } else {
            this.node.prop = 'uplift';
        }

        this.skyAction(this.node.prop);
    },


    JetTubeManager(arr) {
        let isW = arr.indexOf(87) >= 0;
        let isA = arr.indexOf(65) >= 0;
        //let isS = arr.indexOf(83) >= 0;
        let isD = arr.indexOf(68) >= 0;
        if (isW) {
            this.node.prop = 'upFly';
        } else if (isA) {
            this.node.prop = 'leftFly';
        } else if (isD) {
            this.node.prop = 'rightFly';
        } else {
            this.node.prop = 'handLeave';
        }

        this.jetTubeAction(this.node.prop);
    },
    /**
     * 动画管理
     */
    animationManager(state) {
        this.animation.stop();
        if (this.node.currentProp === 'Fall' && (state === 'RunLeft' || state === 'RunRight')) { return; }
        if (this.node.prop === 'Climb') {
            let _sprite = this.node.getComponent(cc.Sprite);
            _sprite.spriteFrame = cc.vv.res["Climb"];
        } else {
            this.animation.play("hero" + state);
        }
    },
    /**
     * 陆地状态要执行的动作
     */
    landAction(state, dir) {
        let obj = {
            'Jump': { y: 13 },
            'RunLeft': { x: 10 },
            'RunRight': { x: 10 },
            'Down': { x: 0 },
            'Roll': { x: 20 },
            'Stand': { x: 0 },
            'Climb': { y: 1 },
            'DoubleJump': { y: 15 },
        }
        if (state === "Roll" || state === "Down") {
            if (this.physicsBoxCollider.size.height === this.heroBoxHeight) {
                this.physicsBoxCollider.size.height /= 2;
                this.physicsBoxCollider.offset.y /= 2;
                //刷新包围盒
                this.physicsBoxCollider.apply();
            }
        }
        if (state === "Jump") {
            if (cc.vv.isDoubleJump) { return; }
            setTimeout(() => {
                cc.vv.isDoubleJump = !cc.vv.isDoubleJump;
            }, 500)

        } if (state === "DoubleJump") {
            cc.vv.isDoubleJump = !cc.vv.isDoubleJump;
        }
        if (state !== "Roll" && state !== "Down") {
            if (this.physicsBoxCollider.size.height === this.heroBoxHeight / 2) {
                this.physicsBoxCollider.size.height *= 2;
                this.physicsBoxCollider.offset.y *= 2;
                this.physicsBoxCollider.apply();
            }
        }

        this.node.scaleX = dir;
        let speed = Object.values(obj[state])[0] * dir;
        if (state === 'Climb') {
            this.rigidBody._b2Body.m_linearVelocity[Object.keys(obj[state])] = (dir === 1) ? -speed : speed;
        } else {
            this.rigidBody._b2Body.m_linearVelocity[Object.keys(obj[state])] = (state === 'Jump' || state === 'DoubleJump') ? Math.abs(speed) : speed;

        }//console.log(this.rigidBody._b2Body.m_linearVelocity.y);
    },
    /**
     * 滚动画执行完成帧回调
     */
    rollFinished() {
        this.rigidBody._b2Body.m_linearVelocity.x = 0;
        this.node.prop = "Down";
        this.animationManager(this.node.prop);
        this.landAction(this.node.prop, this.node.scaleX);

    },
    /**
     * 水里状态要执行的动作
     */
    seaAction(state) {
        this.speed = cc.v2(0, 2)
        //角度转弧度
        // cc.log(123)
        this.aradian = Math.PI / 180 * this.node.rotation;

        this.speed1 = this.speed.rotate(-this.aradian)

        if (state === 'Advance') {
            this.node.x += this.speed1.x;
            this.node.y += this.speed1.y;
        }
        if (state === 'Retreat') {
            this.node.x -= this.speed1.x;
            this.node.y -= this.speed1.y;
        }
        if (state === 'Left') {
            this.node.rotation += -1;
        }
        if (state === 'Right') {
            this.node.rotation += 1;
        }
        if (state === 'Motionless') {
            this.node.rotation += 0
        }

    },
    /**
     * 空中状态要执行的动作
     */
    skyAction(state) {
        //给人物一个向前的线速度
        this.rigidBody._b2Body.m_linearVelocity.x = 16;

        // this.node.rotation = 90;
        //上升
        if (state === 'rising') {
            this.rigidBody._b2Body.m_linearVelocity.y += 0.2;
        }
        //下降
        if (state === 'decline') {
            this.rigidBody._b2Body.m_linearVelocity.y -= 0.2;
        }
        //释放键盘
        if (state === 'uplift') {
            this.rigidBody._b2Body.m_linearVelocity.y -= 0.1;
        }

    },
    /**
     * 喷漆筒状态要执行的动作
     */
    jetTubeAction(state) {
        //上升
        if (state === 'upFly') {
            this.rigidBody._b2Body.m_linearVelocity.y = 5;
        }
        //左移
        if (state === 'leftFly') {
            this.rigidBody._b2Body.m_linearVelocity.x = -5;
            this.node.scaleX = -1;
        }
        //右移
        if (state === 'rightFly') {
            this.rigidBody._b2Body.m_linearVelocity.x = 5;
            this.node.scaleX = 1;
        }
        //没有触控
        if (state === 'handLeave') {
            this.rigidBody._b2Body.m_linearVelocity.x = 0;
            // this.rigidBody._b2Body.m_linearVelocity.y = 0;

        }
    },
    // start(){},
    /**
     * 对外接口
     */
    copyCrash() {
        this.schedule(this.playerCrash, 0.01);
    },
    /**
    * 人物下落状态逻辑
    */
    playerCrash() {
        this.playerSpeed = this.rigidBody._b2Body.m_linearVelocity.y;
        if (Math.ceil(this.playerSpeed) < -1 && this.node.prop !== 'Climb' && this.node.model === 'Land') {
            //下落动画
            this.initPrivateData();
            this.animation.stop();
            this.animation.play("heroFall");
            this.node.prop = 'Fall';
            // this.rigidBody._b2Body.m_linearVelocity.x = 0;
            // cc.vv.isDoubleJump = ture;
        }
        if (Math.ceil(this.playerSpeed) < -25) {//进入死亡状态(实际状态是下落状态)
            //关闭键盘监听
            cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN);
            cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP);
            this.rocketProp.enabledContactListener = false;
            //记录死亡状态并播放死亡动画
            cc.vv.isHeroDie = true;
            this.animation.stop();
            this.animation.play("heroDie");
            this.unschedule(this.playerCrash);
        }
    },
    // 只在两个碰撞体开始接触时被调用一次
    onBeginContact: function (contact, selfCollider, otherCollider) {
        let speed = Math.ceil(this.playerSpeed);
        if (selfCollider.tag === cc.vv.TAG.HERODOWN && this.node.prop === 'Climb'
            && otherCollider.tag === cc.vv.TAG.WALL) {
            this.node.prop = 'Stand';
            this.rigidBody._b2Body.m_linearVelocity.y = 0;
        }
        //爬墙
        if ((selfCollider.tag === cc.vv.TAG.HEROLEFT || selfCollider.tag === cc.vv.TAG.HERORIGHT) &&
            (this.node.prop === "Fall" || this.node.prop === "Jump" || this.node.prop === "DoubleJump") && otherCollider.tag === cc.vv.TAG.WALL) {
            this.node.prop = "Climb";
        }
        let func = () => {//落地
            let speed = Math.ceil(this.playerSpeed);
            //落到地面 浮块 地刺上都需要播放站立动画
            if ((speed === 0 || speed === 1) && !cc.vv.isHeroDie &&
                selfCollider.tag === cc.vv.TAG.HERODOWN &&
                (otherCollider.tag === cc.vv.TAG.WALL || otherCollider.tag === cc.vv.TAG.FLOAT || otherCollider.tag === cc.vv.TAG.DICI)) {
                selfCollider.node.getComponent(cc.Animation).stop();
                selfCollider.node.getComponent(cc.Animation).play("heroStand");
                this.rigidBody._b2Body.m_linearVelocity.x = 0;
                this.rigidBody._b2Body.m_linearVelocity.y = 0;
                this.node.prop = 'Stand';
            }
        }

        //死亡
        if ((speed < -25 && otherCollider.tag === cc.vv.TAG.WALL) ||
            otherCollider.tag === cc.vv.TAG.FLOOR ||
            otherCollider.tag === cc.vv.TAG.DICI ||
            otherCollider.tag === cc.vv.TAG.MINE ||
            otherCollider.tag === cc.vv.TAG.BOMB) {
            let type = (otherCollider.tag === cc.vv.TAG.DICI ||
                otherCollider.tag === cc.vv.TAG.MINE ||
                otherCollider.tag === cc.vv.TAG.BOMB) ? false : true;
            this.heroDeath(type);
            console.log(6666)
        }
        this.funcList.push(func);
    },
    // 只在两个碰撞体结束接触时被调用一次
    onEndContact: function (contact, selfCollider, otherCollider) {
        if ((selfCollider.tag === cc.vv.TAG.HEROLEFT || selfCollider.tag === cc.vv.TAG.HERORIGHT) &&
            this.node.prop === "Climb" && otherCollider.tag === cc.vv.TAG.WALL) {
            this.node.prop = "Fall";
        }
    },
    /**
     * 死亡逻辑
     */
    heroDeath(type) {
        if (!type) {
            if (cc.vv.isHeroDie) { return; }
            cc.vv.isHeroDie = true;
        } else {
            cc.vv.isHeroDie = false;
        }
        cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN);
        cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP);
        this.rigidBody._b2Body.m_linearVelocity.x = 0;
        this.rigidBody._b2Body.m_linearVelocity.y = 0;

        //播放粒子动画
        this.node.model = "Land";
        this.node.prop = "Stand";
        //复活
        setTimeout(() => {
            cc.vv.DeathNum += 1;
            if (!type) {
                cc.vv.isHeroDie = false;
            }
            this.rigidBody._b2Body.m_gravityScale = 3;
            this.node.scaleX = 1;
            this.node.setPosition(cc.v2(cc.vv.currentPos.x, cc.vv.currentPos.y - this.node.height + 30));
            this.node.children[0].active = false;
            this.animation.stop();
            this.node.model = "Land";
            this.node.prop = "Stand";
            this.animation.play("heroStand");
            //开启键盘监听，打开火箭的碰撞
            this.initPrivateData();
            this.initListener();
            this.rocketProp.enabledContactListener = true;
            this.schedule(this.playerCrash, 0.01);
        }, 1000)

    },
    //下一帧处理人物落地之后播放站着的动画
    lateUpdate() {
        this.funcList[0] && this.funcList[0]();
        this.funcList.splice(0, 1);
    },

    //达到终点弹吉他
    takeGuitar() {
        this.animation.play("playGuitar");
        setTimeout(() => {
            this.information.active = true;
        }, 1000)
    },

    update(dt) {
        // console.log(this.node.prop)
        let arr = [];
        for (let i in this.keyList) {
            arr.push(this.keyList[i]);
        }
        this.listenerManager(this.node.model, arr);

    },
    /**
     *  改變狀態
     * @param {*} model 
     */
    changePlayMode(model) {
        // cc.log('改變狀態', model);
        this.node.model = model;
        this.node.prop = 'Jump';
    }

});